<?php
	/**
	 * Tuxxedo Software Engine
	 * =============================================================================
	 *
	 * @author		Kalle Sommer Nielsen 	<kalle@tuxxedo.net>
	 * @author		Ross Masters 		<ross@tuxxedo.net>
	 * @version		1.0
	 * @copyright		Tuxxedo Software Development 2006+
	 * @license		Apache License, Version 2.0
	 * @package		Engine
	 * @subpackage		Library
	 *
	 * =============================================================================
	 */


	/**
	 * Helper namespace, this namespace is for standard helpers that comes 
	 * with Engine.
	 *
	 * @author		Kalle Sommer Nielsen	<kalle@tuxxedo.net>
	 * @author		Ross Masters 		<ross@tuxxedo.net>
	 * @version		1.0
	 * @package		Engine
	 * @subpackage		Library
	 */
	namespace Tuxxedo\Helper;


	/**
	 * Aliasing rules
	 */
	use Tuxxedo\Design;
	use Tuxxedo\Helper\Pagination\Page;
	use Tuxxedo\Registry;


	/**
	 * Include check
	 */
	\defined('\TUXXEDO_LIBRARY') or exit;


	/**
	 * Pagination helper
	 *
	 * @author		Kalle Sommer Nielsen <kalle@tuxxedo.net>
	 * @version		1.0
	 * @package		Engine
	 * @subpackage		Library
	 */
	class Pagination extends Design\InfoAccess implements \Iterator, \Countable
	{
		/**
		 * Iterator instance
		 *
		 * @var		\Tuxxedo\Design\Iterable
		 */
		protected $iterator;

		/**
		 * Iterator pointer position
		 *
		 * @var		integer
		 */
		protected $pointer		= 0;

		/**
		 * Start limit, generated by valid()
		 *
		 * @var		integer
		 */
		protected $limit_start;

		/**
		 * Whether the configuration is valid, generated by valid
		 *
		 * @var		boolean
		 */
		protected $valid		= false;


		/**
		 * Dummy constructor
		 *
	 	 * @param	\Tuxxedo\Registry		The Tuxxedo object reference
		 */
		public function __construct(Registry $registry)
		{
		}

		/**
		 * Sets a new iterator
		 *
		 * @param	\Tuxxedo\Design\Iterable	The iterator to use for the pagination
		 * @return	void				No value is returned
		 */
		public function setIterator(Design\Iteratable $iterator)
		{
			$this->iterator = $iterator;
		}

		/**
		 * Gets the inner iterator
		 *
		 * @return	\Tuxxedo\Design\Iteratable	Returns the inner iterator
		 */
		public function getIterator()
		{
			return($this->iterator);
		}

		/**
		 * Checks if its possible to iterate and if a page 
	 	 * is valid
		 *
		 * @return	boolean				Returns true if the page is valid, otherwise false
		 */
		public function valid()
		{
			$this->valid = false;

			if(!$this->iterator || !isset($this->information['page']) || !isset($this->information['pages']) || !isset($this->information['perpage']) || !isset($this->information['total']) || $this->pointer > \ceil($this->information['total'] / $this->information['perpage']) || ($this->iterator->count() / $this->information['perpage']) == 0)
			{
				return(false);
			}

			$this->valid = true;

			return(true);
		}

		/**
		 * Advances the iterator pointer position
		 *
		 * @return	void				No value is returned
		 */
		public function next()
		{
			++$this->pointer;

			$this->valid = false;
		}

		/**
		 * Gets the current page object
		 *
		 * @return	\Tuxxedo\Helper\Pagination\Page	Returns a page object for the current page or false on error
		 */
		public function current()
		{
			if(!$this->valid)
			{
				return(false);
			}

			return(new Page($this));
		}

		/**
		 * Returns the index for the current position
		 *
		 * @return	integer				Returns the current index
		 */
		public function key()
		{
			return($this->pointer);
		}

		/**
		 * Rewinds the iterator
		 *
		 * @return	void				No value is returned
		 */
		public function rewind()
		{
			$this->pointer 	= 0;
			$this->valid	= false;
		}

		/**
		 * Counts the number of rows within the inner iterator
		 *
		 * @return	integer				Returns the number of rows within the inner iterator, 0 on error
		 */
		public function count()
		{
			return($this->iterator->count());
		}

		/**
		 * Gets the current page limit, requires the mandatory options to be set 
		 * before it can be executed
		 *
		 * @return	integer				Returns the current page limit
		 */
		public function getStartLimit()
		{
			return(($this->information['page'] == 1 ? 0 : ($this->information['page'] - 1) * $this->information['perpage']));
		}
	}
?>